﻿using System;
using System.Diagnostics.Tracing;
using System.Threading;

namespace Sustainalytics.Utils.EventSource
{
    [EventSource(Name = "Sustainalytics-AlertsService")]
    public sealed class AlertsEngineEventSource : System.Diagnostics.Tracing.EventSource
    {
        private static Lazy<AlertsEngineEventSource> _lazyLog = new Lazy<AlertsEngineEventSource>(InitLog, LazyThreadSafetyMode.ExecutionAndPublication);

        public static AlertsEngineEventSource Log => _lazyLog.Value;

        [NonEvent]
        private static AlertsEngineEventSource InitLog()
        {
            var log = new AlertsEngineEventSource();
            log.Ping();

            return log;
        }

        [Event(1, Level = EventLevel.LogAlways)]
        public void Ping()
        {
            if (IsEnabled())
            {
                WriteEvent(1);
            }
        }

        [NonEvent]
        public void Exception(Guid SessionId, string message, Exception ex)
        {
            if (ex != null)
                this.Exception(SessionId, message, ex.GetType().ToString(), ex.Message, ex.ToString());
        }

        [Event(2, Level = EventLevel.Error)]
        public void Exception(Guid SessionId, string message, string exceptionType, string exceptionMessage, string exceptionInformation)
        {
            if (IsEnabled())
                WriteEvent(2, SessionId, message, exceptionType, exceptionMessage, exceptionInformation);
        }

        [Event(3, Level = EventLevel.Informational)]
        public void Test(string controllerName, string httpMethod, int statusCode, string reasonPhrase)
        {
            if (IsEnabled())
            {
                WriteEvent(3, controllerName, httpMethod, statusCode, reasonPhrase);
            }
        }

        [Event(4, Level = EventLevel.Informational)]
        public void InOutEvent(Guid sessionId)
        {
            if (IsEnabled())
            {
                WriteEvent(4, sessionId);
            }
        }

        [Event(5, Level = EventLevel.Informational)]
        public void FileRead(Guid sessionId, DateTime nextAlertSessionSendingDate, DateTime lastSemiMonthlyAlertSession, string unservedClients)
        {
            if (IsEnabled())
            {
                WriteEvent(
                    5,
                    sessionId,
                    nextAlertSessionSendingDate.ToString(System.Globalization.CultureInfo.InvariantCulture),
                    lastSemiMonthlyAlertSession.ToString(System.Globalization.CultureInfo.InvariantCulture),
                    unservedClients
                );
            }
        }

        [Event(6, Level = EventLevel.Informational)]
        public void BlobRead(Guid sessionId, DateTime nextAlertSessionSendingDate, DateTime lastSemiMonthlyAlertSession)
        {
            if (IsEnabled())
            {
                WriteEvent(
                    6,
                    sessionId,
                    nextAlertSessionSendingDate.ToString(System.Globalization.CultureInfo.InvariantCulture),
                    lastSemiMonthlyAlertSession.ToString(System.Globalization.CultureInfo.InvariantCulture)
                );
            }
        }

        [Event(7, Level = EventLevel.Informational)]
        public void MongoEvent(string className, string dbName, string collectionName, string opName, string args, string result)
        {
            if (IsEnabled())
            {
                WriteEvent(7, className, dbName, collectionName, opName, args, result);
            }
        }

        [Event(9, Level = EventLevel.Informational)]
        public void CompletedSuccesfully(Guid sessionId)
        {
            if (IsEnabled())
            {
                WriteEvent(9, sessionId);
            }
        }

        [Event(10, Level = EventLevel.Informational)]
        public void EmailSent(Guid sessionId, string user, string email)
        {
            if (IsEnabled())
            {
                WriteEvent(10, sessionId, user, email);
            }
        }

        [Event(11, Level = EventLevel.Verbose)]
        public void SubscriptionWithoutFeatureUniverses(Guid sessionId, string subscriberId)
        {
            if (IsEnabled())
            {
                WriteEvent(11, sessionId, subscriberId);
            }
        }

        [Event(12, Level = EventLevel.Verbose)]
        public void SubscriptionWithoutClaims(Guid sessionId, string subscriberId)
        {
            if (IsEnabled())
            {
                WriteEvent(12, sessionId, subscriberId);
            }
        }

        [Event(13, Level = EventLevel.Verbose)]
        public void SubscriptionAccepted(Guid sessionId, string subscriberId)
        {
            if (IsEnabled())
            {
                WriteEvent(13, sessionId, subscriberId);
            }
        }

        [Event(14, Level = EventLevel.Verbose)]
        public void SubscriptionRejectedBecauseUserAccess(Guid sessionId, string subscriberId)
        {
            if (IsEnabled())
            {
                WriteEvent(14, sessionId, subscriberId);
            }
        }

        [Event(15, Level = EventLevel.Informational)]
        public void ProcessAlertStarted(Guid sessionId)
        {
            if (IsEnabled())
            {
                WriteEvent(15, sessionId, "Process alerts started");
            }
        }

        [Event(16, Level = EventLevel.Informational)]
        public void ProcessAlertEnded(Guid sessionId)
        {
            if (IsEnabled())
            {
                WriteEvent(16, sessionId, "Process alerts ended");
            }
        }

        [Event(17, Level = EventLevel.Informational)]
        public void NoNeedToProcess(Guid sessionId)
        {
            if (IsEnabled())
            {
                WriteEvent(17, sessionId, "No need to process");
            }
        }

        [Event(18, Level = EventLevel.Verbose)]
        public void SubscriptionRejectedBecauseUserHasInvalidAccount(Guid sessionId, string subscriberId)
        {
            if (IsEnabled())
            {
                WriteEvent(18, sessionId, subscriberId);
            }
        }

        [Event(19, Level = EventLevel.Informational)]
        public void SubscriptionWithoutCompanies(Guid sessionId, Guid subscriberId, Guid compId)
        {
            if (IsEnabled())
            {
                WriteEvent(19, sessionId, subscriberId, compId, "Subscription Without Companies");
            }
        }

        [Event(21, Level = EventLevel.Informational)]
        public void NoPorfolioForSubscription(Guid sessionId, Guid subscriberId)
        {
            if (IsEnabled())
            {
                WriteEvent(21, sessionId, subscriberId, "No portfolio for subscription");
            }
        }

        [Event(22, Level = EventLevel.Informational)]
        public void NoLastSync(Guid sessionId)
        {
            if (IsEnabled())
            {
                WriteEvent(22, sessionId);
            }
        }

        [Event(23, Level = EventLevel.Informational)]
        public void LastSyncNotEnded(Guid sessionId)
        {
            if (IsEnabled())
            {
                WriteEvent(23, sessionId);
            }
        }

        [Event(24, Level = EventLevel.Informational)]
        public void LastSyncOlderThan24Hours(Guid sessionId)
        {
            if (IsEnabled())
            {
                WriteEvent(24, sessionId);
            }
        }

        [Event(25, Level = EventLevel.Informational)]
        public void AlertWithoutCompanyInCorporateData(Guid sessionId)
        {
            if (IsEnabled())
            {
                WriteEvent(25, sessionId);
            }
        }
    }
}
